#include "stdafx.h"
#include "render/rendermgr.h"
#include "./hpobj.h"

#define DEFAULT_LIFE 4
#define DEFAULT_WIDTH 8
#define DEFAULT_HEIGHT 4.5
#define HP_ALPHA 50
#define HP_FONTSIZE 9
#define LP_DISTANCE 0.4

HpObj::HpObj(string strName, Point pos, float z, Color color)
: m_lifepoint(DEFAULT_LIFE)
, m_lifelist(new unsigned int[DEFAULT_LIFE])
, m_bkglist(0)
, m_textObj(strName, Point(pos.x + 0.5, pos.y + DEFAULT_HEIGHT - 2), z, HP_FONTSIZE, color)
{
	memcpy(&m_color, &color, sizeof(Color));

	float rect[4];

	rect[0] = pos.x;
	rect[1] = pos.y;
	rect[2] = pos.x + DEFAULT_WIDTH;
	rect[3] = pos.y + DEFAULT_HEIGHT;

	LoadBackground(rect, z - 1);
	LoadLifeVertexs(rect, z);

	RenderMgr::GetInstance().OnAfterRender += EventObject<OnAfterRenderFunc>(this, &HpObj::OnTopMostRender);
}

HpObj::~HpObj()
{
	RenderMgr::GetInstance().OnAfterRender -= EventObject<OnAfterRenderFunc>(this, &HpObj::OnTopMostRender);
	glDeleteLists(m_bkglist, 1);
	for (int i = 0; i < DEFAULT_LIFE; ++i)
	{
		glDeleteLists(m_lifelist[i], 1);
	}

	delete[] m_lifelist;
	m_lifelist = NULL;
}

void HpObj::SetVisible(bool v)
{
	m_textObj.SetVisible(v);
	m_bVisible = v;
}

void HpObj::OnTopMostRender(float differTime)
{
	if (!m_bVisible)
		return;

	glCallList(m_bkglist);

	for (int i = 0; i < m_lifepoint; ++i)
	{
		if (!m_lifelist)
			break;

		glCallList(m_lifelist[i]);
	}
}

void HpObj::DecreaseLife()
{
	m_lifepoint--;
}

int HpObj::GetLifePoint()
{
	return m_lifepoint;
}

void HpObj::LoadBackground(float rect[4], float posZ)
{
	m_bkglist = glGenLists(1);
	glNewList(m_bkglist, GL_COMPILE);

	glEnable(GL_LIGHTING);
	glEnable(GL_BLEND); 
	glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glBegin(GL_QUADS);
	glColor4ub(255, 0, 0, HP_ALPHA);	
	glVertex3f(rect[0], rect[1], posZ);
	glVertex3f(rect[2], rect[1], posZ);
	glColor4ub(255, 255, 255, HP_ALPHA);	
	glVertex3f(rect[2], rect[3], posZ);
	glVertex3f(rect[0], rect[3], posZ);
	glEnd();

	glColor4ub(0, 0, 0, HP_ALPHA);
	glBegin(GL_LINES);
	glVertex3f(rect[0], rect[1], posZ);
	glVertex3f(rect[2], rect[1], posZ);

	glVertex3f(rect[2], rect[1], posZ);
	glVertex3f(rect[2], rect[3], posZ);

	glVertex3f(rect[2], rect[3], posZ);
	glVertex3f(rect[0], rect[3], posZ);

	glVertex3f(rect[0], rect[3], posZ);
	glVertex3f(rect[0], rect[1], posZ);
	glEnd();

	glDisable(GL_BLEND);
	glDisable(GL_LIGHTING);

	glEndList();
}

void HpObj::LoadLifeVertexs(float rect[4], float posZ)
{
	float lpwidth = (DEFAULT_WIDTH - 5 * LP_DISTANCE) / DEFAULT_LIFE;
	float posX = rect[0] + LP_DISTANCE;
	float posTop = rect[1] + DEFAULT_HEIGHT - 3;
	float posBottom = rect[1] + 0.5;

	for (int i = 0; i < DEFAULT_LIFE; ++i)
	{
		m_lifelist[i] = glGenLists(1);
		glNewList(m_lifelist[i], GL_COMPILE);

		glBegin(GL_QUADS);
		glColor3ub(m_color.r, m_color.g, m_color.b);
		glVertex3f(posX, posTop, posZ);
		glVertex3f(posX, posBottom, posZ);
		glVertex3f(posX + lpwidth, posBottom, posZ);
		glVertex3f(posX + lpwidth, posTop, posZ);

		glEnd();

		glEndList();

		posX += LP_DISTANCE + lpwidth;
	}
}

void HpObj::GetSize(int& cx, int& cy)
{
	cx = DEFAULT_WIDTH;
	cy = DEFAULT_HEIGHT;
}